package top.lshaci.learning.springboot.redis.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializer;
import top.lshaci.learning.springboot.redis.handle.MessageHandle;

/**
 * RedisConfig
 *
 * @author lshaci
 * @since 1.0.0
 */
@Slf4j
@Configuration
public class RedisConfig {

    /**
     * redis消息监听器容器
     * 可以添加多个监听不同话题的redis监听器，只需要把消息监听器和相应的消息订阅处理器绑定，该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     *
     * @param connectionFactory
     * @param listenerAdapter
     * @return
     */
    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);

        //订阅多个频道
        container.addMessageListener(listenerAdapter, new PatternTopic("c"));
//        container.addMessageListener(listenerAdapter, new PatternTopic("c"));

        //序列化对象（特别注意：发布的时候需要设置序列化；订阅方也需要设置序列化）

        container.setTopicSerializer(RedisSerializer.string());
        return container;
    }

    /**
     * 表示监听一个频道
     */
    @Bean
    public MessageListenerAdapter listenerAdapter(MessageHandle delegate) {
        //这个地方 是给 messageListenerAdapter 传入一个消息接受的处理器，
        // 利用反射的方法调用 delegate::handleMessage, 方法名可以修改
        MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(delegate);
        messageListenerAdapter.setSerializer(valueSerializer());
        return messageListenerAdapter;
    }

    @Bean
    public GenericFastJsonRedisSerializer valueSerializer() {
        log.debug("Config generic fast json redis serializer...");
        return new GenericFastJsonRedisSerializer();
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        template.setValueSerializer(valueSerializer());
        return template;
    }
}
